<template>
	<view style="margin-top: 400rpx;">
		<button 
			@touchstart="streamRecord" 
			@touchend="streamRecordEnd" 
			type="primary"
			class="fc-white">语音识别按钮</button>
		<view> 语音识别内容：{{currentText}} </view>

		<!-- 语音动画 -->
		<view class="prompt" v-if="animation">
			<section class="dots-container">
				<view class="dot"></view>
				<view class="dot"></view>
				<view class="dot"></view>
				<view class="dot"></view>
				<view class="dot"></view>
			</section>
			<text>录音中...</text>
		</view>
	</view>
</template>

<script>
	const plugin = requirePlugin("WechatSI")
	let voiceManager = plugin.getRecordRecognitionManager()
	
	export default {
		data() {
			return {
				currentText: "",
				animation: false,
			}
		},
		methods: {
			streamRecord() {
				console.log('开始录音')
				this.animation = true
				voiceManager.start({
					lang: "zh_CN",
					context: this // 确保上下文正确
				})
			},
			
			streamRecordEnd() {
				console.log('结束录音')
				this.animation = false
				voiceManager.stop()
				uni.vibrateShort()
			},
			
			initRecord() {
				// 实时识别结果
				voiceManager.onRecognize = (res) => {
					if (res.result) {
						this.currentText = res.result
					}
				}
				
				// 最终识别结果
				voiceManager.onStop = (res) => {
					console.log('识别结果', res)
					if (res.result) {
						this.currentText = res.result
					} else {
						uni.showToast({ title: '未识别到内容', icon: 'none' })
					}
				}
				
				// 错误处理
				voiceManager.onError = (err) => {
					console.error('识别错误', err)
					this.animation = false
					uni.showToast({ title: '识别失败', icon: 'none' })
				}
			}
		},
		onLoad() {
			this.initRecord()
		}
	}
</script>

<style lang="scss" scoped>
	/* 保持原有样式不变 */
	.prompt {
		width: 100%;
		height: 160rpx;
		position: fixed;
		bottom: 50vh;
	}

	.prompt text {
		position: absolute;
		bottom: 2px;
		color: white;
		left: calc(45%);
		animation: puls 1.5s infinite ease-in-out;
	}

	.dots-container {
		display: flex;
		align-items: center;
		justify-content: center;
		height: 80px;
		width: 45%;
		position: absolute;
		bottom: 0px;
		left: calc(27.5%);
		background-color: rgba(0, 0, 0, 0.5);
		border-radius: 40rpx;
	}

	.dot {
		height: 28rpx;
		width: 28rpx;
		margin-right: 20rpx;
		border-radius: 20rpx;
		background-image: linear-gradient(#5396FF, #AEDAFF);
		animation: pulse 1.5s infinite ease-in-out;
	}

	.dot:last-child {
		margin-right: 0;
	}

	.dot:nth-child(1) {
		animation-delay: -0.3s;
	}

	.dot:nth-child(2) {
		animation-delay: -0.1s;
	}

	.dot:nth-child(3) {
		animation-delay: 0.1s;
	}

	@keyframes pulse {
		0% {
			transform: scale(0.8);
			background-color: #66A3FF;
			box-shadow: 0 0 0 0 rgba(102, 163, 255, 0.7);
		}
		50% {
			transform: scale(1.2);
			background-color: #ADD8FF;
			box-shadow: 0 0 0 10px rgba(174, 218, 255, 0);
		}
		100% {
			transform: scale(0.8);
			background-color: #66A3FF;
			box-shadow: 0 0 0 0 rgba(102, 163, 255, 0.7);
		}
	}

	@keyframes puls {
		0% { transform: translateY(0px) }
		50% { transform: translateY(-4px) }
		100% { transform: translateY(0px) }
	}
</style>
<!-- <template>
  <view class="layout-column">
    <camera :device-position="position" 
            :flash="flash"
            @error="error"
            class="camera" 
            :style="'height:'+cHei+'px;'">
      <cover-image 
        class="close-img active" 
        @click="close" 
        src="/static/miniprogram/custom-camera/close.png"/>
      <cover-view class="water-marker">
        <cover-view class="time">{{ time }}</cover-view>
        <cover-view class="div"></cover-view>
        <cover-view class="date">{{ date }}</cover-view>
        <cover-view class="week">{{ week }}</cover-view>
        <cover-view class="address">{{ address }}</cover-view>
      </cover-view>
      <cover-image 
        class="result"
        @click="handlePre" 
        :src="photo"
        v-show="photo"/>
    </camera>
    <view class="bottom layout-row less-center">
      <image :src="'/static/miniprogram/custom-camera/light-'+(flash == 'off' ? 'on' : 'off')+'.png'"
             :class="'light-img active '+(position == 'front' ? 'hidden' : '')"
             @click="handleLight"/>
      <view class="layout-row center cicle-outside">
        <view class="cicle-inside active"
              @click="doTakePhoto"/>
      </view>
      <image src="/static/miniprogram/custom-camera/switch.png"
             class="switch-img active"
             @click="handlePosition"/>
    </view>
    <canvas canvas-id="firstCanvas"
            class="canvas"
            :style="'width:'+canvasW+'px;height: '+canvasH+'px'"/>
  </view>
</template>

<script>
export default {
  data() {
    return {
      cHei: 0,
      position: 'back',
      flash: 'off',
      photo: '',
      canvasW: 0,
      canvasH: 0,
      fristTimedraw: true,
      working: false,
      time: "14:30",
      date: "2023-09-12",
      week: "星期二",
      address: "江西省南昌市东湖区广场北路2号"
    };
  },
  onShow() {
    this.cHei = uni.getSystemInfoSync().windowHeight - uni.upx2px(300);
  },
  methods: {
    close() {
      uni.navigateBack({
        delta: 1
      });
    },
    error(e) {
      console.log('camera error', e);
    },
    takePhoto() {
      const ctx = uni.createCameraContext();
      ctx.takePhoto({
        quality: 'high',
        success: (res) => {
          console.log('takePhoto success', res);
          this.drawPhoto(res.tempImagePath);
        }
      });
    },
    doTakePhoto() {
      this.working = true;
      this.takePhoto();
      if (this.fristTimedraw) {
        setTimeout(() => {
          this.takePhoto();
          this.fristTimedraw = false;
        }, 500);
      }
    },
    drawPhoto(path) {
      uni.getImageInfo({
        src: path,
        success: (res) => {
          const ctx = uni.createCanvasContext('firstCanvas');
          this.canvasW = res.width;
          this.canvasH = res.height;
          ctx.drawImage(path, 0, 0, res.width, res.height);

          const w = 460;
          const h = 180;
          const x = 30;
          const y = res.height - 210;
          const r = 20;

          ctx.beginPath();
          ctx.setFillStyle('transparent');
          ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
          ctx.moveTo(x + r, y);
          ctx.lineTo(x + w - r, y);
          ctx.lineTo(x + w, y + r);
          ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
          ctx.lineTo(x + w, y + h - r);
          ctx.lineTo(x + w - r, y + h);
          ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
          ctx.lineTo(x + r, y + h);
          ctx.lineTo(x, y + h - r);
          ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
          ctx.lineTo(x, y + r);
          ctx.lineTo(x + r, y);
          ctx.fill();
          ctx.closePath();
          ctx.clip();
          ctx.setFillStyle('rgba(255, 255, 255, 0.2)');
          ctx.fillRect(x, y, w, h);

          ctx.setFontSize(55);
          ctx.setFillStyle('#FFFFFF');
          ctx.fillText(this.time, x + 30, y + 70);

          const timeW = ctx.measureText(this.time).width;
          ctx.setFillStyle('#FFFF00');
          ctx.fillRect(x + 30 + timeW + 30, y + 20, 8, 70);

          ctx.setFontSize(30);
          ctx.setFillStyle('#FFFFFF');
          ctx.fillText(this.date, x + 30 + timeW + 30 + 50, y + 45);

          ctx.setFontSize(28);
          ctx.setFillStyle('#FFFFFF');
          ctx.fillText(this.week, x + 30 + timeW + 30 + 50, y + 85);

          ctx.setFontSize(24);
          ctx.fillText(this.address, 60, y + 140);

          ctx.draw(false, () => {
            uni.showLoading({
              title: '正在生成水印照片'
            });
            uni.canvasToTempFilePath({
              canvasId: 'firstCanvas',
              destWidth: this.canvasW * 2,
              destHeight: this.canvasH * 2,
              success: (res1) => {
                this.working = false;
                uni.hideLoading();
                this.photo = res1.tempFilePath;
              }
            });
          });
        }
      });
    },
    savePhoto(path) {
      uni.saveImageToPhotosAlbum({
        filePath: path,
        success: (res) => {
          uni.showToast({
            title: '照片已保存到相册',
            icon: 'none',
            duration: 2000
          });
        }
      });
    },
    handleLight() {
      if (this.working) {
        return;
      }
      if (this.flash === 'off') {
        this.flash = 'on';
      } else {
        this.flash = 'off';
      }
    },
    handlePosition() {
      if (this.working) {
        return;
      }
      if (this.position === 'back') {
        this.position = 'front';
        this.flash = 'off';
      } else {
        this.position = 'back';
      }
    },
    handlePre() {
      if (this.working) {
        return;
      }
      uni.previewImage({
        current: 0,
        urls: [this.photo],
        success: (res) => {
          console.log(res);
        }
      });
    }
  }
};
</script>

<style scoped lang="scss">
page {
  width: 100%;
  height: 100%;
}
.camera {
  width: 100%;
  background: #999999;
}
.close-img {
  width: 48rpx;
  height: 48rpx;
  margin-top: 110rpx;
  margin-left: 40rpx;
}
.light-img {
  width: 48rpx;
  height: 48rpx;
}
.switch-img {
  width: 57rpx;
  height: 48rpx;
}
.bottom {
  width: 100%;
  height: 300rpx;
  background: black;
  justify-content: space-around;
}
.cicle-outside {
  width: 150rpx;
  height: 150rpx;
  border: 5rpx solid #fff;
  border-radius: 50%;
  margin-left: 50%;
  left: -75rpx;
  position: absolute;
}
.cicle-inside {
  width: 130rpx;
  height: 130rpx;
  border-radius: 50%;
  background: #fff;
  margin-left: 10rpx;
  margin-top: 10rpx;
}
.hidden {
  visibility: hidden;
}
.water-marker {
  position: absolute;
  left: 30rpx;
  bottom: 30rpx;
  width: 430rpx;
  height: 180rpx;
  background: rgba($color: #ffffff, $alpha: 0.2);
  border-radius: 20rpx;
}
.time {
  font-size: 55rpx;
  color: white;
  position: absolute;
  top: 20rpx;
  left: 30rpx;
}
.div {
  border-radius: 3rpx;
  width: 8rpx;
  height: 70rpx;
  background: yellow;
  position: absolute;
  top: 20rpx;
  left: 200rpx;
}
.date {
  font-size: 28rpx;
  color: white;
  position: absolute;
  top: 20rpx;
  left: 240rpx;
  width: 180rpx;
}
.week {
  font-size: 28rpx;
  color: white;
  position: absolute;
  top: 60rpx;
  left: 240rpx;
}
.address {
  font-size: 24rpx;
  color: white;
  position: absolute;
  top: 120rpx;
  left: 30rpx;
  bottom: 30rpx;
  word-break: break-all;
  word-wrap: break-word;
  white-space: pre-line;
}
.canvas {
  position: absolute;
  top: -999999rpx;
  width: 100%;
}
.result {
  width: 100rpx;
  height: 100rpx;
  position: absolute;
  right: 30rpx;
  bottom: 30rpx;
  background: white;
  border-radius: 50%;
}
</style> -->